#include <thr_channel.h>
#include <pthread.h>
#include <syslog.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <server_conf.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <proto.h>

struct thr_channel_ent_st {
    chnid_t chnid;
    pthread_t tid;
};

static struct thr_channel_ent_st thr_channels[CHNNR] = {0};
static int tid_nextpos = 0;

static void* thr_channel_snd(void* arg) {
    struct mlib_listentry_st* list_entry = arg;
    struct msg_channel_st* sbufp = NULL;
    ssize_t len = 0;
    int ret = -1;

    sbufp = (struct msg_channel_st*)malloc(MSG_CHANNEL_MAX);
    if (sbufp == NULL) {
        syslog(LOG_ERR, "malloc error,%s\n", strerror(errno));
        exit(1);
    }
    memset(sbufp, 0, MSG_CHANNEL_MAX);

    sbufp->chnid = list_entry->chnid;
    while (1) {
        len = mlib_readchn(list_entry->chnid, sbufp->data, MSG_MAX_DATA);

        ret = sendto(serverSd, sbufp, sizeof(chnid_t)+len, 0, (void*)&sndAddr, sndAddrLen);
        if (ret < 0) {
            syslog(LOG_ERR, "sendto error,%s,chnid:%d,serverSd:%d,len:%ld\n", strerror(errno), sbufp->chnid, serverSd, len);
            exit(1);
        }
        // syslog(LOG_INFO, "chnid:%d,data:%s\n", sbufp->chnid, (char*)(sbufp->data));

        sched_yield();  // 发送完成主动出让调度器
    }

    pthread_exit(NULL);
}

int thr_channel_create(struct mlib_listentry_st* list_entry) {
    if (!list_entry) {
        return -1;
    }
    
    int err = -1;

    err = pthread_create(&thr_channels[tid_nextpos].tid, NULL, thr_channel_snd, list_entry);
    if (err != 0) {
        syslog(LOG_ERR, "pthread_create error,%s\n", strerror(errno));
        return err;
    }

    thr_channels[tid_nextpos].chnid = list_entry->chnid;
    tid_nextpos++;

    return 0;
}

int thr_channel_destroy(struct mlib_listentry_st* list_entry) {
    if (!list_entry) {
        return -1;
    }
    
    int i = 0;
    int ret = -1;
    for (i = 0; i < CHNNR; i++) {
        if (thr_channels[i].chnid == list_entry->chnid) {
            ret = pthread_cancel(thr_channels[i].tid);
            if (ret != 0) {
                syslog(LOG_ERR, "pthread_cancel error\n");
                return -1;
            }
            break;
        }
    }

    pthread_join(thr_channels[i].tid, NULL);

    return 0;
}

int thr_channel_destroyAll(void) {
    return 0;
}
